#include <linux/module.h>
#include <linux/pci.h>
#include "drv_ecum.h"
#include "drv_acm.h"
#include "drv_dim.h"
#include "drv_dom.h"
#include "drv_aim.h"
#include "drv_aom.h"
#include "drv_pim.h"
#include "drv_ptm.h"
#include "drv_iepem.h"
#include "drv_soem.h"

static int __init pcie_drivers_init(void)
{
    int ret = 0;

    /* 注册 ECUM 模块驱动 */
    ret = pci_register_driver(&pcie_ecum_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", ECUM_DRV_NAME, ret);
        goto err_ecum;
    }
    pr_debug("Register PCIe driver %s success\n", ECUM_DRV_NAME);

    /* 注册 ACM 模块驱动 */
    ret = pci_register_driver(&pcie_acm_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", ACM_DRV_NAME, ret);
        goto err_acm;
    }
    pr_debug("Register PCIe driver %s success\n", ACM_DRV_NAME);

    /* 注册 DIM 模块驱动 */
    ret = pci_register_driver(&pcie_dim_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", DIM_DRV_NAME, ret);
        goto err_dim;
    }
    pr_debug("Register PCIe driver %s success\n", DIM_DRV_NAME);

    /* 注册 DOM 模块驱动 */
    ret = pci_register_driver(&pcie_dom_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", DOM_DRV_NAME, ret);
        goto err_dom;
    }
    pr_debug("Register PCIe driver %s success\n", DOM_DRV_NAME);

    /* 注册 AIM 模块驱动 */
    ret = pci_register_driver(&pcie_aim_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", AIM_DRV_NAME, ret);
        goto err_aim;
    }
    pr_debug("Register PCIe driver %s success\n", AIM_DRV_NAME);

    /* 注册 AOM 模块驱动 */
    ret = pci_register_driver(&pcie_aom_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", AOM_DRV_NAME, ret);
        goto err_aom;
    }
    pr_debug("Register PCIe driver %s success\n", AOM_DRV_NAME);

    /* 注册 PIM 模块驱动 */
    ret = pci_register_driver(&pcie_pim_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", PIM_DRV_NAME, ret);
        goto err_pim;
    }
    pr_debug("Register PCIe driver %s success\n", PIM_DRV_NAME);

    /* 注册 PTM 模块驱动 */
    ret = pci_register_driver(&pcie_ptm_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", PTM_DRV_NAME, ret);
        goto err_ptm;
    }
    pr_debug("Register PCIe driver %s success\n", PTM_DRV_NAME);

    /* 注册 IEPEM 模块驱动 */
    ret = pci_register_driver(&pcie_iepem_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", IEPEM_DRV_NAME, ret);
        goto err_iepem;
    }
    pr_debug("Register PCIe driver %s success\n", IEPEM_DRV_NAME);

    /* 注册 SOEM 模块驱动 */
    ret = pci_register_driver(&pcie_soem_driver);
    if (ret) {
        pr_err("Register PCIe driver %s failed, errno %d\n", SOEM_DRV_NAME, ret);
        goto err_soem;
    }
    pr_debug("Register PCIe driver %s success\n", SOEM_DRV_NAME);

    return 0;

err_soem:
    pci_unregister_driver(&pcie_iepem_driver);
err_iepem:
    pci_unregister_driver(&pcie_ptm_driver);
err_ptm:
    pci_unregister_driver(&pcie_pim_driver);
err_pim:
    pci_unregister_driver(&pcie_aom_driver);
err_aom:
    pci_unregister_driver(&pcie_aim_driver);
err_aim:
    pci_unregister_driver(&pcie_dom_driver);
err_dom:
    pci_unregister_driver(&pcie_dim_driver);
err_dim:
    pci_unregister_driver(&pcie_acm_driver);
err_acm:
    pci_unregister_driver(&pcie_ecum_driver);
err_ecum:

    return ret;
}

static void __exit pcie_drivers_exit(void)
{
    pci_unregister_driver(&pcie_ecum_driver);
    pr_debug("Unregister PCIe driver %s success\n", ECUM_DRV_NAME);
    
    pci_unregister_driver(&pcie_acm_driver);
    pr_debug("Unregister PCIe driver %s success\n", ACM_DRV_NAME);

    pci_unregister_driver(&pcie_dim_driver);
    pr_debug("Unregister PCIe driver %s success\n", DIM_DRV_NAME);

    pci_unregister_driver(&pcie_dom_driver);
    pr_debug("Unregister PCIe driver %s success\n", DOM_DRV_NAME);

    pci_unregister_driver(&pcie_aim_driver);
    pr_debug("Unregister PCIe driver %s success\n", AIM_DRV_NAME);

    pci_unregister_driver(&pcie_aom_driver);
    pr_debug("Unregister PCIe driver %s success\n", AOM_DRV_NAME);

    pci_unregister_driver(&pcie_pim_driver);
    pr_debug("Unregister PCIe driver %s success\n", PIM_DRV_NAME);

    pci_unregister_driver(&pcie_ptm_driver);
    pr_debug("Unregister PCIe driver %s success\n", PTM_DRV_NAME);

    pci_unregister_driver(&pcie_iepem_driver);
    pr_debug("Unregister PCIe driver %s success\n", IEPEM_DRV_NAME);

    pci_unregister_driver(&pcie_soem_driver);
    pr_debug("Unregister PCIe driver %s success\n", SOEM_DRV_NAME);
}

module_init(pcie_drivers_init);
module_exit(pcie_drivers_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jason");
MODULE_DESCRIPTION("PCIe Char Device Driver");
MODULE_VERSION("0.1");
